﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;

namespace Extended.WPF.Core.Helpers
{
    public static class SizeHelper
    {
        public static Size Infinite { get { return infinite; } }
        public static Size Zero { get { return zero; } }
        static Size infinite;
        static Size zero;
        static SizeHelper()
        {
            infinite = new Size(double.PositiveInfinity, double.PositiveInfinity);
            zero = new Size(0, 0);
        }
        public static void Deflate(ref Size size, Thickness padding)
        {
            size.Width = Math.Max(0, size.Width - (padding.Left + padding.Right));
            size.Height = Math.Max(0, size.Height - (padding.Top + padding.Bottom));
        }
        public static void Inflate(ref Size size, Thickness padding)
        {
            size.Width = Math.Max(0, size.Width + padding.Left + padding.Right);
            size.Height = Math.Max(0, size.Height + padding.Top + padding.Bottom);
        }
        public static void UpdateMinSize(ref Size minSize, Size size)
        {
            UpdateMinSize(ref minSize, size, true, true);
        }
        public static void UpdateMinSize(ref Size minSize, Size size, bool updateWidth, bool updateHeight)
        {
            if (updateWidth)
                minSize.Width = Math.Min(minSize.Width, size.Width);
            if (updateHeight)
                minSize.Height = Math.Min(minSize.Height, size.Height);
        }
        public static void UpdateMaxSize(ref Size maxSize, Size size)
        {
            UpdateMaxSize(ref maxSize, size, true, true);
        }
        public static void UpdateMaxSize(ref Size maxSize, Size size, bool updateWidth, bool updateHeight)
        {
            if (updateWidth)
                maxSize.Width = Math.Max(maxSize.Width, size.Width);
            if (updateHeight)
                maxSize.Height = Math.Max(maxSize.Height, size.Height);
        }
        public static Size ToMeasureValid(Size size)
        {
            return ToMeasureValid(size, true, true);
        }
        public static Size ToMeasureValid(Size size, bool updateWidth, bool updateHeight)
        {
            return new Size(updateWidth ? ToMeasureValid(size.Width) : size.Width, updateHeight ? ToMeasureValid(size.Height) : size.Height);
        }
        public static bool IsMeasureValid(double length)
        {
            return !double.IsInfinity(length) && !double.IsNaN(length) && length >= 0;
        }
        static double ToMeasureValid(double length)
        {
            return IsMeasureValid(length) ? length : 0d;
        }
        public static Size ToInfinity(Size size, bool isInfinityWidth, bool isInfinityHeight)
        {
            return new Size(isInfinityWidth ? double.PositiveInfinity : size.Width, isInfinityHeight ? double.PositiveInfinity : size.Height);
        }
        public static Size Parse(string s)
        {
            var result = new Size();
            string[] numbers = s.Split(ThicknessHelper.NumericListSeparator);
            if (numbers != null && numbers.Length == 2)
            {
                result.Width = double.Parse(numbers[0], CultureInfo.InvariantCulture);
                result.Height = double.Parse(numbers[1], CultureInfo.InvariantCulture);
            }
            return result;
        }

        public static bool AreClose(Size size1, Size size2)
        {
            return (size1.Width.AreClose(size2.Width) && size1.Height.AreClose(size2.Height));
        }
      
    }
}
